package ha.web.games_manager;

import ha.web.database.DBConnector;
import ha.web.database.UserId;
import ha.web.exceptions.GameException;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;

public class GM {
	private static GM singleton = null;
	
	private List<UserId> waiting_list; //list of users waiting to be added to a game
	
	private HashMap<Integer,UserId> players;  //<userId,UserObj>
	
	private HashMap<Integer, Integer> game_playing;//<userid,gameId> 
	 
	private HashMap<Integer, GameRunning> games; // games[game_id]["chat"]
															 // games[game_id]["player_turn"] = player_id
															 // games[game_id]["table"]
	private GM()
	{	
		//waiting_list.clear();
		games = new HashMap<Integer, GameRunning>();
		waiting_list = new ArrayList<UserId>();
		game_playing = new HashMap<Integer, Integer>();
		players = new HashMap<Integer, UserId>();
	}
	
	public static GM getInstance() 
	{
		if(singleton==null)
			singleton = new GM();
		return singleton;
	}
	
	public List<String> getPlayers(int gameId) {
		return games.get(new Integer(gameId)).getPlayers();
	}
	public void updateStatistics(int userId, boolean won)
	{
		//get user current statistics:
		
		
		
		//update user statistics:
	}
	public void gameEnded(int userId, boolean won)
	{
		int game_id = get_game_id(userId);
		List<String> game_players = get_players(game_id);
		//update db statistics
		
		//remove game + users 
		games.remove(game_id); 
		players.remove(game_players.get(0));
		players.remove(game_players.get(1));
		game_playing.remove(game_players.get(0));
		game_playing.remove(game_players.get(1));
	}
	
	public List<String> get_players(int gameId) {
		return getPlayers(gameId);
	}
	
	public int get_game_id(int userId) {
		if (game_playing.containsKey(userId)) 
			return game_playing.get(userId);			
		return -1;
	}

	public boolean my_turn(int player) {
		Integer gameId = game_playing.get(player);
		//check not in waiting list:
		if (waiting_list.contains(player))
			return false;
		//check player turn:
		return games.get(gameId).itIsTurn(player);
	}
	
	public String getPlayerTurnByGameId(int gameId) {
		return games.get(new Integer(gameId)).getPlayerNameTurn();
	}
	
//	public void switch_turn(String gameId) {
//		games.get(new Integer(gameId)).switchTurn();	
//	}
	
	public void switch_turn(int gameId) {
		games.get(gameId).switchTurn();	
	}

	
	public void player_login(int userId) {
		UserId p = getPlayerById(userId);
		if (waiting_list.size() > 0){
			UserId other = waiting_list.get(0);
			waiting_list.remove(0);
			GameRunning newGame = new GameRunning(other,p);
			games.put(newGame.getGameId(), newGame);
			game_playing.put(userId,newGame.getGameId());
			game_playing.put(other.getUserID(),newGame.getGameId());
		}else // add player and return
			waiting_list.add(p);
	}
	
	public boolean validate_player_move(String move, Integer gameId, int who_moved)
	{
//		Integer moved =0;
		try {
			if (!games.get(gameId).itIsTurn(who_moved))
				return false;
			if (move == "") 
				return false;
			String temp_board = games.get(gameId).getTable();
			String[] moves = move.split(";");
	
			for(int i=0; i< moves.length; i++) {
				  String[] m = moves[i].split("->");
				  if (m.length !=2) return false;
				  
				  String[] from = m[0].split("-");
				  String[] to =   m[1].split("-");
				  if (from.length !=2) return false;
				  if (to.length !=2) return false;
				  if (! valid_move(from, to, temp_board)) return false;
				  //move valid - update board
				  char a = temp_board.charAt(Integer.parseInt(from[0]) + Integer.parseInt(from[1])*9);
				  char b = temp_board.charAt(Integer.parseInt(to[0]) + Integer.parseInt(to[1])*9);
				  
				  temp_board = temp_board.substring(0,Integer.parseInt(to[0]) + Integer.parseInt(to[1])*9)
						  +a +temp_board.substring(Integer.parseInt(to[0]) + Integer.parseInt(to[1])*9 + 1);
				  
				  temp_board = temp_board.substring(0,Integer.parseInt(from[0]) + Integer.parseInt(from[1])*9)
						  +b +temp_board.substring(Integer.parseInt(from[0]) + Integer.parseInt(from[1])*9 + 1);
			}
			// if got to here - can save moves:
			
			//update board
//			games.get(gameId).setTable(temp_board);
			//update player turn
			switch_turn(gameId);

			return true; // to be removed latter
			
		} catch (Exception e) {
			return false; // to be removed latter
		}
	}
	private boolean valid_move(String[] from, String[] to, String board)
	{
		char piece_from = board.charAt(Integer.parseInt(from[0]) + Integer.parseInt(from[1])*9);
		char piece_to = board.charAt(Integer.parseInt(to[0]) + Integer.parseInt(to[1])*9);
		
		//check pieces
		
		//check moved one
		
		//check moved two
		return true;
	}
	
	// CHAT //
	public void add_line_to_chat(int player, String line)
	{
		if (get_game_id(player) == -1)
		{	
			return;
		}
		
		games.get(get_game_id(player)).addLineToChat(player, line);
		
	}
	
	public String get_chat(int player) {
		if (get_game_id(player) == -1)
			return "player not in game!";
		else
			return games.get(game_playing.get(player)).getChat();
	}
	
	public void setLastMove(int user,String lastMove) throws GameException {
		games.get(get_game_id(user)).setLastMove(user, lastMove);
	}
	
	public String getLastMove(int user) {
		return games.get(get_game_id(user)).getLastMove(user);
	}
	
	public String getTable(int user) {
		return games.get(get_game_id(user)).getTable();
	}
	
	public UserId getPlayerById(int userId) {
		return players.get(userId);
	}

	public boolean IsUserAtDB(int userId) {
		return DBConnector.IsUserAtDB(getPlayerById(userId));
	}

	public int createNewUser(String userName, String userPass) {
		UserId newUser = new UserId(userName, userPass);
		players.put(newUser.getUserID(), newUser);
		return newUser.getUserID();
	}
}
